# −*− coding: UTF−8 −*− 

import random

def additionsaufgabe(min=0, max=100):
    """Ermittelt zwei Zufallszahlen im Bereich [min, max)
    und liefert ein Tuple mit drei Zeichenketten zurück, 
    die die zugehörige Additionsaufgabe darstellen: 
    (frage, ergebnis, antwortsatz)
    """

    z1 = random.randint(min, max)
    z2 = random.randint(min, max)

    frage = "%s + %s = " % (z1, z2)
    ergebnis = "%s" % (z1 + z2)
    antwortsatz = frage + ergebnis

    return (frage, ergebnis, antwortsatz)

def multiplikationsaufgabe(min=3, max=12):
    """Ermittelt zwei Zufallszahlen im Bereich [min, max)
    und liefert ein Tuple mit drei Zeichenketten zurück, 
    die die zugehörige Multiplikationsaufgabe darstellen: 
    (frage, ergebnis, antwortsatz)
    """

    z1 = random.randint(min, max)
    z2 = random.randint(min, max)

    frage = "%s * %s = " % (z1, z2)
    ergebnis = "%s" % (z1 * z2)
    antwortsatz = frage + ergebnis

    return (frage, ergebnis, antwortsatz)

# Mapping um Benutzereingaben auf die zugehörigen
# Funktionen für die Aufgabenstellung abzubilden
aufgaben = {'a': additionsaufgabe,
            'm': multiplikationsaufgabe,
            }

# Mapping um Benutzereingaben auf volle Namen zu expandieren
typen = {'a': 'addition',
         'm': 'multiplikation',
         }

# Mapping zur Definition der Schwierigkeitsgrade für die
# verschiedenen Aufgabentypen
schwierigkeit = {'l': {'addition': [1, 50],
                       'multiplikation': [1, 5],
                       },
                 'm': {'addition': [0, 100],
                       'multiplikation': [0, 10],
                       },
                 's': {'addition': [30, 150],
                       'multiplikation': [3, 12],
                       },
                 }

def auswahl(grad):
    """Hilfsfunktion zur Abfrage des Aufgabentyps
    """
    eingabe = raw_input("\nAdditionsaufgabe [A] oder Multiplikationsaufgabe [m]? ")
    typ = typen.get(eingabe, 'addition')
    bereich = schwierigkeit[grad][typ]
    return aufgaben.get(eingabe, additionsaufgabe), bereich

def schwierigkeitsgrad():
    """Hilfsfunktion zur Abfrage des Schwierigkeitsgrades
    """
    wahl = raw_input("Leicht [l], mittel [M] oder schwer [s]? ")
    wahl = wahl.lower().strip()
    if wahl not in ['l', 'm', 's']:
        wahl = 'm'
    return wahl

# Mapping zur Definition der Notenskala
notenskala = ((90, 'sehr gut'),
              (80, 'gut'),
              (70, 'befriedigend'),
              (50, 'ausreichend'),
              (30, 'mangelhaft'),
              )

def bewerte(r, f):
    """Hilfsfunktion zur Benotung des Schülers

    Eingabeparameter: r(ichtig), f(alsch)

    Berechnet den Prozentsatz der richtig gelösten Aufgaben
    und ermittelt daraus die Note mit Hilfe des 'notenskala'
    mappings.

    Gibt eine Zeichenkette mit dem Prädikat zurück.
    """
    prozent = float(r)*100/(r+f)
    for level, note in notenskala:
        if prozent >= level:
            return note

def trainer():
    """Hauptkontrollfunktion des Aufgabentrainers

    Enthält die zentrale Abfrageschleife und wertet
    die Benutzereingaben aus. 
    """
    fertig = False
    richtig = 0
    falsch = 0

    grad = schwierigkeitsgrad()

    while not fertig:
        aufgabe, bereich = auswahl(grad)
        frage, ergebnis, antwortsatz = aufgabe(bereich[0], bereich[1])

        antwort = raw_input("\n"+frage).strip()

        if antwort == ergebnis:
            richtig += 1
            print "\nRichtig! ", antwortsatz
        else:
            falsch += 1
            print "\nFalsch! ", antwortsatz
            
        nochmal = raw_input("\nNochmal? (J/n)")
        if nochmal.lower() == 'n':
            fertig = True

    note = bewerte(richtig, falsch)
    resultat = "\n%s!\nDu hast %s Aufgaben richtig gelöst und %s Fehler gemacht." 
    print resultat % (note.title(), richtig, falsch)


if __name__ == "__main__":
    """Startet die Hauptkontrollfunktion 'trainer', wenn das Module 
    von der Kommandozeile aufgerufen wird.
    """
    trainer()

